package com.crm.common.component;

import com.crm.common.exception.BaseException;
import com.crm.common.exception.BizBaseException;
import com.crm.common.model.DataResponse;
import com.crm.common.model.DhResponse;
import com.crm.common.model.Enum.ResponseCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description:全局异常
 * @author: lixq-f
 * @create: 2021/03/23
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理请求参数
     *
     * @param request
     * @return
     */
    private Map<String, Object> handleRequestParam(HttpServletRequest request) {
        // 获取所有参数
        Enumeration<?> enu = request.getParameterNames();
        Map<String, Object> map = new HashMap<>();
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            if (paraName != null && paraName.toLowerCase().contains("password")) {
                map.put(paraName, "***");
            } else {
                map.put(paraName, request.getParameter(paraName));
            }
        }

        // 获取访问的url
        String url = request.getRequestURL().toString();
        // 获取请求的方法
        String method = request.getMethod();

        map.put("url", url);
        map.put("method", method);

        return map;
    }


    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handlerBizExp(HttpServletRequest request, Exception e) {
        logger.error("发生异常，请求信息 {} ", this.handleRequestParam(request), e);
        return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode(), ResponseCodeEnum.SERVICE_ERROR.getResponseValue());
    }


    @ExceptionHandler(value = {BaseException.class, IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handlerBaseException(HttpServletRequest request, Exception e) {
        logger.error("发生异常请求:\n{},\n{},\n{},", request.getMethod(), request.getRequestURL().toString(), e.getMessage(), e);
        return new DhResponse(ResponseCodeEnum.PARAMETER_ERROR.getResponseCode(), e.getMessage());
    }


    @ExceptionHandler(value = HttpMessageConversionException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handlerHttpMessageConversionException(HttpServletRequest request, Exception e) {
        logger.error("发生异常请求:\n{},\n{},\n{}", request.getMethod(), request.getRequestURL().toString(), e.getMessage(), e);
        return new DhResponse(ResponseCodeEnum.PARAMETER_ERROR.getResponseCode(), "参数转换异常，请检查");
    }


    @ExceptionHandler(value = org.springframework.web.bind.MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handleValidatorException(HttpServletRequest request, Exception e) {
        logger.error("发生异常请求:\n{},\n{},\n{}", request.getMethod(), request.getRequestURL().toString(), e.getMessage(), e);
        StringBuilder sb = new StringBuilder();
        org.springframework.web.bind.MethodArgumentNotValidException exception = (org.springframework.web.bind.MethodArgumentNotValidException) e;
        BindingResult bindingResult = exception.getBindingResult();
        List<ObjectError> errors = bindingResult.getAllErrors();
        for (ObjectError error : errors) {
            sb.append(error.getDefaultMessage()).append(";");
        }
        sb.deleteCharAt(sb.length() - 1);
        return new DhResponse(ResponseCodeEnum.PARAMETER_ERROR.getResponseCode(), sb.toString());
    }



    @ExceptionHandler(value = org.springframework.web.method.annotation.MethodArgumentTypeMismatchException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handlerArgsException(HttpServletRequest request, Exception e){
        org.springframework.web.method.annotation.MethodArgumentTypeMismatchException exception = (org.springframework.web.method.annotation.MethodArgumentTypeMismatchException) e;
        logger.error("发生异常请求:\n{},\n{},\n{}",request.getMethod(),request.getRequestURL().toString(),e.getMessage(),e);
        return new DhResponse(ResponseCodeEnum.PARAMETER_ERROR.getResponseCode(), e.getMessage());
    }


    @ExceptionHandler(value = BizBaseException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public DataResponse handlerBizException(HttpServletRequest request, Exception e){
        logger.error("发生业务异常:\n{},\n{},\n{}",request.getMethod(),request.getRequestURL().toString(),e.getMessage(),e);
        return new DhResponse(ResponseCodeEnum.BUSINESS_ERROR.getResponseCode(), e.getMessage());
    }





}
